#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
认证模块专项测试脚本

用于快速测试调度系统的认证功能，包括：
- 用户登录
- 获取用户信息
- 修改密码
- Token验证

使用方法：
python auth_test.py
"""

import requests
import json
from datetime import datetime

# 配置
BASE_URL = "http://localhost:5000/api"
TEST_USERS = [
    {"username": "admin", "password": "admin123"},
    {"username": "manager1", "password": "password"},
    {"username": "user1", "password": "password"},
    {"username": "user2", "password": "password"}
]

class AuthTester:
    def __init__(self, base_url=BASE_URL):
        self.base_url = base_url
        self.session = requests.Session()
        
    def test_login(self, username, password):
        """测试用户登录"""
        url = f"{self.base_url}/auth/login"
        data = {
            "username": username,
            "password": password
        }
        
        try:
            response = self.session.post(url, json=data)
            if response.status_code == 200:
                result = response.json()
                print(f"✓ 用户 {username} 登录成功")
                print(f"  Token: {result['access_token'][:50]}...")
                print(f"  用户信息: {result['user']['name']} ({result['user']['role']})")
                return result['access_token'], result['user']
            else:
                print(f"✗ 用户 {username} 登录失败: {response.text}")
                return None, None
        except Exception as e:
            print(f"✗ 登录请求异常: {e}")
            return None, None
    
    def test_profile(self, token):
        """测试获取用户信息"""
        url = f"{self.base_url}/auth/profile"
        headers = {"Authorization": f"Bearer {token}"}
        
        try:
            response = self.session.get(url, headers=headers)
            if response.status_code == 200:
                user_info = response.json()['user']
                print(f"✓ 获取用户信息成功: {user_info['name']}")
                return user_info
            else:
                print(f"✗ 获取用户信息失败: {response.text}")
                return None
        except Exception as e:
            print(f"✗ 获取用户信息异常: {e}")
            return None
    
    def test_change_password(self, token, old_password, new_password):
        """测试修改密码"""
        url = f"{self.base_url}/auth/change-password"
        headers = {"Authorization": f"Bearer {token}"}
        data = {
            "old_password": old_password,
            "new_password": new_password
        }
        
        try:
            response = self.session.post(url, json=data, headers=headers)
            if response.status_code == 200:
                print(f"✓ 密码修改成功")
                return True
            else:
                print(f"✗ 密码修改失败: {response.text}")
                return False
        except Exception as e:
            print(f"✗ 密码修改异常: {e}")
            return False
    
    def test_invalid_token(self):
        """测试无效Token"""
        url = f"{self.base_url}/auth/profile"
        headers = {"Authorization": "Bearer invalid_token_12345"}
        
        try:
            response = self.session.get(url, headers=headers)
            if response.status_code == 422:  # JWT错误
                print("✓ 无效Token正确被拒绝")
                return True
            else:
                print(f"✗ 无效Token处理异常: {response.status_code}")
                return False
        except Exception as e:
            print(f"✗ 无效Token测试异常: {e}")
            return False
    
    def test_no_token(self):
        """测试无Token访问"""
        url = f"{self.base_url}/auth/profile"
        
        try:
            response = self.session.get(url)
            if response.status_code == 401:  # 未授权
                print("✓ 无Token访问正确被拒绝")
                return True
            else:
                print(f"✗ 无Token访问处理异常: {response.status_code}")
                return False
        except Exception as e:
            print(f"✗ 无Token测试异常: {e}")
            return False
    
    def run_comprehensive_test(self):
        """运行综合认证测试"""
        print("开始认证模块综合测试...")
        print(f"测试目标: {self.base_url}")
        print("=" * 50)
        
        success_count = 0
        total_count = 0
        
        # 测试所有用户登录
        print("\n1. 测试用户登录")
        print("-" * 30)
        tokens = {}
        for user in TEST_USERS:
            total_count += 1
            token, user_info = self.test_login(user['username'], user['password'])
            if token:
                success_count += 1
                tokens[user['username']] = {
                    'token': token,
                    'password': user['password'],
                    'user_info': user_info
                }
        
        # 测试获取用户信息
        print("\n2. 测试获取用户信息")
        print("-" * 30)
        for username, data in tokens.items():
            total_count += 1
            if self.test_profile(data['token']):
                success_count += 1
        
        # 测试修改密码（仅对admin用户）
        if 'admin' in tokens:
            print("\n3. 测试修改密码")
            print("-" * 30)
            admin_data = tokens['admin']
            
            # 修改密码
            total_count += 1
            if self.test_change_password(admin_data['token'], admin_data['password'], 'new_password_123'):
                success_count += 1
                
                # 恢复密码
                total_count += 1
                if self.test_change_password(admin_data['token'], 'new_password_123', admin_data['password']):
                    success_count += 1
        
        # 测试安全性
        print("\n4. 测试安全性")
        print("-" * 30)
        
        # 测试无效Token
        total_count += 1
        if self.test_invalid_token():
            success_count += 1
            
        # 测试无Token访问
        total_count += 1
        if self.test_no_token():
            success_count += 1
        
        # 测试错误的用户名密码
        print("\n5. 测试错误凭据")
        print("-" * 30)
        total_count += 1
        token, _ = self.test_login("wrong_user", "wrong_password")
        if token is None:
            print("✓ 错误凭据正确被拒绝")
            success_count += 1
        
        # 输出测试结果
        print("\n" + "=" * 50)
        print("认证测试结果汇总:")
        print(f"总测试数: {total_count}")
        print(f"通过: {success_count}")
        print(f"失败: {total_count - success_count}")
        print(f"成功率: {(success_count/total_count*100):.1f}%")
        
        if success_count == total_count:
            print("\n🎉 所有认证测试通过！")
        else:
            print(f"\n⚠️  有 {total_count - success_count} 个测试失败")

def main():
    """主函数"""
    print("调度系统认证模块测试")
    print("=" * 30)
    
    tester = AuthTester()
    tester.run_comprehensive_test()

if __name__ == "__main__":
    main()